package com.jhgk.jhcee.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jhgk.jhcee.common.constant.AuthConstant;
import com.jhgk.jhcee.common.constant.MessageConstant;
import com.jhgk.jhcee.common.domain.TableListModel;
import com.jhgk.jhcee.common.domain.UserModel;
import com.jhgk.jhcee.common.enums.BasisResultEnum;
import com.jhgk.jhcee.common.exception.Asserts;
import com.jhgk.jhcee.common.exception.UserException;
import com.jhgk.jhcee.common.resultful.BasisResultful;
import com.jhgk.jhcee.data.auth.entity.SysRoleInfo;
import com.jhgk.jhcee.data.auth.entity.SysUserInfo;
import com.jhgk.jhcee.data.auth.mapper.SysRoleInfoMapper;
import com.jhgk.jhcee.data.auth.mapper.SysUserInfoMapper;
import com.jhgk.jhcee.data.auth.mapper.SysUserRoleRelationMapper;
import com.jhgk.jhcee.system.domain.dao.SysRoleInfoDao;
import com.jhgk.jhcee.system.domain.dao.SysUserInfoDao;
import com.jhgk.jhcee.system.domain.model.SysUserInfoModel;
import com.jhgk.jhcee.system.domain.model.SysUserLoginParam;
import com.jhgk.jhcee.system.service.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: xiezhongping
 * @description:
 * @date: 2021/8/16 14:36.
 */
@Service(value = "SysUserInfoServiceImpl")
public class SysUserInfoServiceImpl extends ServiceImpl<SysUserInfoMapper, SysUserInfo> implements SysUserInfoService {

    @Autowired
    SysUserInfoMapper sysUserInfoMapper;

    @Autowired
    SysUserInfoDao sysUserInfoDao;

    @Autowired
    SysRoleInfoMapper sysRoleInfoMapper;

    @Autowired
    SysUserRoleRelationMapper sysUserRoleMapper;

    @Autowired
    SysRoleInfoDao sysRoleInfoDao;

    @Autowired
    SysRoleInfoService sysRoleInfoService;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    SysUserCacheService sysUserCacheService;

    @Autowired
    private AuthService authService;

    @Resource(name = "SysUserOrgRelationServiceImpl")
    SysUserOrgRelationService sysUserOrgRelationService;

    @Resource(name = "SysUserRoleRelationServiceImpl")
    SysUserRoleRelationService sysUserRoleRelationService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public BasisResultful<UserModel> loadUserByUsername(String username) {
        if (StringUtils.isBlank(username)) {
            return BasisResultful.fail(BasisResultEnum.PARAM_IS_NULL);
        }
        QueryWrapper<SysUserInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        wrapper.eq("status", 1);
        SysUserInfo sysUserInfo = sysUserInfoMapper.selectOne(wrapper);
        if (null == sysUserInfo) {
            throw new UserException(MessageConstant.USER_NULL);
        }
        UserModel userModel = new UserModel();
        BeanUtil.copyProperties(sysUserInfo, userModel);
        userModel.setId(sysUserInfo.getUserId());
        List<SysRoleInfo> roleList = sysRoleInfoMapper.getRoleList(sysUserInfo.getUserId());
        if (CollUtil.isNotEmpty(roleList)) {
            List<String> roleStrList = roleList.stream().map(item -> item.getRoleId() + "_" + item.getRoleName()).collect(Collectors.toList());
            userModel.setRoles(roleStrList);
        }
        return BasisResultful.success(userModel);
    }

    @Override
    public BasisResultful<SysUserInfo> getCurrentUser() {
        String user = request.getHeader(AuthConstant.USER_TOKEN_HEADER);
        if (StringUtils.isBlank(user)) {
            Asserts.fail(BasisResultEnum.UNAUTHORIZED);
        }
        UserModel userModel = JSONUtil.toBean(user, UserModel.class);
        SysUserInfo sysUserInfo = sysUserCacheService.getUser(userModel.getId());
        if (null != sysUserInfo) {
            return BasisResultful.success(sysUserInfo);
        } else {
            QueryWrapper<SysUserInfo> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", userModel.getId());
            sysUserInfo = sysUserInfoMapper.selectOne(wrapper);
            sysUserCacheService.setUser(sysUserInfo);
            return BasisResultful.success(sysUserInfo);
        }
    }

    @Override
    public BasisResultful<SysUserInfo> register(SysUserInfo sysUserInfo) {
        if (null == sysUserInfo) {
            return BasisResultful.fail(BasisResultEnum.PARAM_IS_NULL);
        }
        // 根据用户名查询用户是否存在
        BasisResultful<Object> accountExist = this.isAccountExist(sysUserInfo.getUsername());
        if (accountExist.getCode() == BasisResultEnum.SUCCESS.getCode()) {
            // 用户存在
            return BasisResultful.fail(BasisResultEnum.USER_VALID);
        }
        String encodePwd = passwordEncoder.encode(sysUserInfo.getPassword());
        sysUserInfo.setPassword(encodePwd);
        boolean save = this.save(sysUserInfo);
        if (save) {
            SysUserInfo userInfo = sysUserInfoMapper.selectByUserName(sysUserInfo.getUsername());
            return BasisResultful.success(userInfo);
        }
        return BasisResultful.fail();
    }

    @Override
    public BasisResultful<Object> getInfo() {
        BasisResultful<SysUserInfo> currentUser = getCurrentUser();
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("username", currentUser.getResult().getUsername());
        resultMap.put("menus", sysRoleInfoService.getMenuList(currentUser.getResult().getUserId()));
        resultMap.put("icon", currentUser.getResult().getIcon());
        List<SysRoleInfo> roleList = sysRoleInfoService.getRoleList(currentUser.getResult().getUserId());
        if (!roleList.isEmpty()) {
            List<String> roles = roleList.stream().map(SysRoleInfo::getRoleName).collect(Collectors.toList());
            resultMap.put("roles", roles);
        }
        return BasisResultful.success(resultMap);
    }

    @Override
    public BasisResultful login(SysUserLoginParam sysUserLoginParam) {
        if (StrUtil.isEmpty(sysUserLoginParam.getUsername()) || StrUtil.isEmpty(sysUserLoginParam.getPassword())) {
            Asserts.fail("用户名或密码不能为空！");
        }
        Map<String, String> params = new HashMap<>();
        params.put("client_id", AuthConstant.ADMIN_CLIENT_ID);
        params.put("client_secret", "123456");
        params.put("grant_type", "password");
        params.put("username", sysUserLoginParam.getUsername());
        params.put("password", sysUserLoginParam.getPassword());
        BasisResultful restResult = authService.getAccessToken(params);
        if (BasisResultEnum.SUCCESS.getCode() == restResult.getCode() && restResult.getResult() != null) {
            sysUserInfoMapper.updateLoginTime(sysUserLoginParam.getUsername());
        }
        return restResult;
    }

    @Override
    public BasisResultful<Object> userList(SysUserInfoModel model) {
        if (null == model) {
            return BasisResultful.fail(BasisResultEnum.PARAM_IS_NULL);
        }
        PageHelper.startPage(model.getPage(), model.getPageSize());
        List<SysUserInfoModel> sysUserInfos = sysUserInfoDao.searchDetailList(model);
        if (sysUserInfos.isEmpty()) {
            return BasisResultful.success(sysUserInfos);
        }
        sysUserInfos.forEach(user -> user.setId(String.valueOf(user.getUserId())));
        PageInfo<SysUserInfoModel> pageInfo = new PageInfo<>(sysUserInfos);
        return BasisResultful.success(new TableListModel(pageInfo.getList(), pageInfo.getTotal()));
    }

    @Override
    public BasisResultful<Object> isAccountExist(String username) {
        if (StringUtils.isBlank(username)) {
            return BasisResultful.fail(BasisResultEnum.PARAM_IS_NULL);
        }
        QueryWrapper<SysUserInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        List<SysUserInfo> sysUserInfos = sysUserInfoMapper.selectList(wrapper);
        if (sysUserInfos.isEmpty()) {
            return BasisResultful.fail(BasisResultEnum.USER_NOT_EXIST);
        }
        return BasisResultful.success(sysUserInfos.get(0));
    }

    @Override
    public BasisResultful<Object> updateUser(SysUserInfoModel model) {
        if (null == model) {
            return BasisResultful.fail(BasisResultEnum.PARAM_IS_NULL);
        }
        QueryWrapper<SysUserInfo> userWrapper = new QueryWrapper<>();
        userWrapper.eq("user_id", model.getUserId());
        if (!this.update(model, userWrapper)) {
            return BasisResultful.fail();
        }
        // 更新角色信息
        if (!sysUserRoleRelationService.updateByUserId(model.getUserId(), model.getRoleId())) {
            return BasisResultful.fail();
        }
        SysUserInfo userInfo = sysUserInfoMapper.selectOne(userWrapper);
        BasisResultful<Object> resultful = sysUserOrgRelationService.updateRelation(userInfo.getUserId(), model.getOrgId());
        if (resultful.getCode() != BasisResultEnum.SUCCESS.getCode()) {
            return BasisResultful.fail();
        }
        return BasisResultful.success(sysUserInfoDao.searchUserDetail(model.getUserId()));
    }

    @Override
    public BasisResultful<Object> deleteUser(Long userId) {
        if (null == userId) {
            return BasisResultful.fail(BasisResultEnum.PARAM_IS_NULL);
        }
        QueryWrapper<SysUserInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        int delete = sysUserInfoMapper.delete(wrapper);
        return delete > 0 ? BasisResultful.success() : BasisResultful.fail();
    }

    @Override
    public BasisResultful<Object> addUser(SysUserInfoModel model) {
        if (null == model) {
            return BasisResultful.fail(BasisResultEnum.PARAM_IS_NULL);
        }
        // 根据用户名查询用户是否存在
        BasisResultful<Object> accountExist = this.isAccountExist(model.getUsername());
        if (accountExist.getCode() == BasisResultEnum.SUCCESS.getCode()) {
            // 用户存在
            return BasisResultful.fail(BasisResultEnum.USER_VALID);
        }
        // 新增账号信息
        SysUserInfo userInfo = model;
        String encodePwd = passwordEncoder.encode(model.getPassword());
        userInfo.setPassword(encodePwd);
        boolean save = this.save(userInfo);
        if (!save) {
            return BasisResultful.fail(BasisResultEnum.ADD_FAIL);
        }
        // 查询新增账号信息
        SysUserInfo sysUserInfo = sysUserInfoMapper.selectByUserName(model.getUsername());
        // 新增角色信息
        Boolean aBoolean = sysUserRoleRelationService.saveByUserId(sysUserInfo.getUserId(), model.getRoleId());
        if (!aBoolean) {
            return BasisResultful.fail(BasisResultEnum.SAVE_ROLE_RELATION_FAIL);
        }
        // 新增部门信息
        BasisResultful<Object> resultful = sysUserOrgRelationService.addRelation(sysUserInfo.getUserId(), model.getOrgId());
        if (resultful.getCode() != BasisResultful.success().getCode()) {
            return resultful;
        }
        return BasisResultful.success();
    }

    @Override
    public BasisResultful<Object> setUserStatus(Long userId, Integer status) {
        if (null == userId || null == status) {
            return BasisResultful.fail(BasisResultEnum.PARAM_IS_NULL);
        }
        Boolean aBoolean = sysUserInfoMapper.setUserStatus(userId, status);
        if (!aBoolean) {
            return BasisResultful.fail(BasisResultEnum.QUERY_IS_NULL);
        }
        return BasisResultful.success();
    }

}
